<?php
declare (strict_types=1);

namespace app\common\library\upload\driver;

use app\common\library\upload\Driver;
use OSS\OssClient;
use think\facade\Cache;

class AliOss extends Driver
{

    private $config = [];

    public function __construct()
    {
        $this->config = config('system.ali_oss');
    }

    /**
     * @title 普通文件上传 (大小不超过5MB)
     * @param string $file 上传的input框的name值
     * @param string $save_name 保存的文件名,不穿默认生成随机文件名
     * @param string $type 文件类型
     * @return array
     * *@author wanghao
     */
    public function upload($file, $save_name = '', $type = ''): array
    {

        if (empty($this->config['access_key_id'])) {
            $this->error = '阿里oss配置不存在';
            return [];
        }
        if (!$this->checkFile($file)) return [];
        //转小写
        if ($save_name != '') {
            $ext = strtolower(substr(strrchr($save_name, '.'), 1));
        } else {
            $ext = strtolower(substr(strrchr($_FILES[$file]['name'], '.'), 1));
        }

        if (!$this->checkExt($ext)) return [];

        try {
            //实例化对象 将配置传入
            $OssClient = new OssClient($this->config['access_key_id'], $this->config['access_key_secret'], $this->config['endpoint']);

            //这里是有sha1加密 生成文件名 之后连接上后缀
            if ($save_name == '') {
                $save_name = uniqid() . '.' . $ext;
            } else {
                $save_name = strtolower($save_name);
            }

            if ($type == '') $type = $ext;

            $fileName = 'upload/' . $type . '/' . date("Ym/d") . '/' . $save_name;
            //执行阿里云上传
            $result = $OssClient->uploadFile($this->config['bucket_name'], $fileName, $_FILES[$file]['tmp_name']);

            if (!empty($this->config['url'])) {
                $url = $this->config['url'] . $fileName;
            } else {
                $url = str_replace('http://', 'https://', $result['info']['url']);  //上传资源地址
            }

            $other_info = $OssClient->getObjectMeta($this->config['bucket_name'], $fileName);
            $size = $other_info['content-length'] ?? 0;
            $md5 = $other_info['etag'] ?? 0;

        } catch (\Exception $e) {
            $this->error = $e->getMessage();
            return [];
        }
        return [
            'url' => $url,
            'size' => $size,
            'md5' => $md5,
        ];
    }

    /**
     * @title 分片上传大文件
     * @param string $file 上传的input框的name值
     * @param string $save_name 保存的文件名,不穿默认生成随机文件名
     * @param string $type 文件类型
     * @return array
     * *@author wanghao
     */
    public function uploadBig($file, $save_name, $type = ''): array
    {
        //获取配置
        if (empty($this->config['access_key_id'])) {
            $this->error = '阿里oss配置不存在';
            return [];
        }
        if (!$this->checkFile($file)) return [];
        $save_name = strtolower($save_name);
        $ext = substr(strrchr($save_name, '.'), 1);
        if (!$this->checkExt($ext)) return [];

        try {
            //实例化对象 将配置传入
            $OssClient = new OssClient($this->config['access_key_id'], $this->config['access_key_secret'], $this->config['endpoint']);
            //这里是有sha1加密 生成文件名 之后连接上后缀
            if ($type == '') $type = $ext;
            $fileName = 'upload/' . $type . '/' . date("Ym/d") . '/' . $save_name;
            //执行阿里云上传
            $position = 0;

            $result = Cache::store('redis')->get(md5($save_name));
            if ($result) {
                $position = intval($result);
            }
            $result = $OssClient->appendFile($this->config['bucket_name'], $fileName, $_FILES[$file]['tmp_name'], $position);

            Cache::store('redis')->set(md5($save_name), $result, 600);

            if (!empty($this->config['url'])) {
                $url = $this->config['url'] . $fileName;
            } else {
                $url = 'https://' . $this->config['bucket_name'] . '.' . $this->config['endpoint'] . '/' . $fileName;  //上传资源地址
            }
            $other_info = $OssClient->getObjectMeta($this->config['bucket_name'], $fileName);
            $size = $other_info['content-length'] ?? 0;
            $md5 = $other_info['etag'] ?? 0;
        } catch (\Exception $e) {
            $this->error = $e->getMessage();
            return [];
        }
        return [
            'url' => $url,
            'size' => $size,
            'md5' => $md5,
        ];
    }

}